package com.cloud.utils;

import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.TimeUnit;

/**
 * 主键自动生成
 */
@Component
public class HandwritingRedisOrderIDGenerate {
    @Resource
    public RedisTemplate<String, Object> redisTemplate;

    /**
     * TODO 获取唯一Id（20位）
     *
     * @param key   redis-key前缀
     * @param delta 默认初始自增值
     * @return java.lang.String
     */
    public String getOrderId(String key, Long delta) {

        try {
            // delta为空默认值1
            if (null == delta) {
                delta = 1L;
            }
            // 生成14位的时间戳(每秒使用新的时间戳当key)
            String timeStamp = new SimpleDateFormat("yyMMddHHmmss").format(new Date());
            System.out.println("timeStamp++++++" + timeStamp);
            // 获得redis-key
//            String newKey = key + ":" + timeStamp;
            // 获取自增值（时间戳+自定义key）  key是时间戳  防止该key永不过期
            Long increment = redisTemplate.opsForValue().increment(key + timeStamp, delta);
            // 设置时间戳生成的key的有效期为1秒
            redisTemplate.expire(key + timeStamp, 1, TimeUnit.SECONDS);
            // 获取订单号，时间戳 + 唯一自增Id( 6位数,不够前方补0)
            String result = timeStamp + String.format("%06d", increment);
            //result.compareTo((String) redisTemplate.opsForValue().get("member_max_id"))<0  认为是发生了时间回拨
            if (redisTemplate.opsForValue().get("member_max_id") != null && result.compareTo((String) redisTemplate.opsForValue().get("member_max_id")) < 0) {

                //通过修改redis的步长解决
                Long incrementBack = redisTemplate.opsForValue().increment(key + timeStamp, 500);
                redisTemplate.expire(key + timeStamp, 1, TimeUnit.SECONDS);
                result = timeStamp + String.format("%06d", incrementBack);
                return result;
            }
            // 存入最大id 防止时间回拨
            redisTemplate.opsForValue().set("member_max_id", result);
            return result;
        } catch (Exception e) {
            // redis 宕机时采用时间戳加随机数
            String timeStamp = new SimpleDateFormat("yyMMddHHmmss").format(new Date());
            //12位时间戳到 + 6位随机数
            String random = String.format("%06d", (int) (Math.random() * 1000000));
            timeStamp += random;
            return timeStamp;
        }
    }
}